package luit.mmt02.secutity;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.Cipher;

import android.util.Base64;
import android.util.Log;

public class RSAControl 
{
	byte[] encryptedText = null;
    byte[] decryptedText = null;
    BigInteger m;
    BigInteger e;
    RSAPrivateKeySpec keySpecPriv;
    RSAPublicKeySpec keySpecPub;
    KeyFactory fact;
    Cipher rsaCipher;
    PrivateKey KeyPri;
    PublicKey KeyPu;
    Cipher Cip;
    String tag = "RSAControl";
    
    
    public RSAControl(String str_private, String str_public) 
    {
    	File f = new File(str_private);
    	File f1 = new File(str_public);
    	if(f.isFile() && f1.isFile())
    	{
			this.KeyPri = readPrivKeyFromFile(str_private);
			this.KeyPu = readPubKeyFromFile(str_public);
			Log.v(tag, "Khoi tao cap key thanh cong");
    	}
    	else
    	{
    		Log.v(tag, "ERR khong ton tai cap key RSA, goi ham keymanage truoc" + e.toString());
    	}
		// TODO Auto-generated constructor stub
	}
    
    public RSAControl(String pathkey, boolean flag) // true la truyen private key, false la truyen public key
    {
    	File f = new File(pathkey);
    	if(f.isFile())
    	{
    		if(flag) // neu true tao private key
    		{
    			this.KeyPri = readPrivKeyFromFile(pathkey);
    			Log.v(tag, "create key private...");
    		}
    		else
    		{
    			this.KeyPu = readPubKeyFromFile(pathkey);
    			Log.v(tag, "create key public ...");
    		}
    	}
    }
    
	PrivateKey readPrivKeyFromFile(String keyFileName)
    {
        try
        {
        	ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(new FileInputStream(keyFileName)));
            m = (BigInteger) oin.readObject();
            e = (BigInteger) oin.readObject();
            keySpecPriv = new RSAPrivateKeySpec(m, e);
            fact = KeyFactory.getInstance("RSA");
            KeyPri = fact.generatePrivate(keySpecPriv);
            
        } catch (Exception x)
        {
        	Log.v(tag, "Loi readprikey");
        } 
        return KeyPri;
    }
    PublicKey readPubKeyFromFile(String keyFileName)
    {
       
        try {
        	 ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(new FileInputStream(keyFileName)));
            m = (BigInteger) oin.readObject();
            e = (BigInteger) oin.readObject();
            keySpecPub = new RSAPublicKeySpec(m, e);
            fact = KeyFactory.getInstance("RSA");
            KeyPu = fact.generatePublic(keySpecPub);
            
        } catch (Exception x)
        {
        	Log.v(tag, "Loi readpublicKey");
        } 
        return KeyPu;
    }
    
    public String encrypt_baomat(String input) // muon goi ham nay phai set key, dung pulich key ma hoa
    {
        String str = "";
        try
        {
        	Log.v(tag, "bao mat dung key public de ma hoa...");
            Cip = Cipher.getInstance("RSA");
            Cip.init(Cipher.ENCRYPT_MODE, KeyPu);
            byte []utf8 = input.getBytes("UTF8");
            byte []enc = Cip.doFinal(utf8);
            str = Base64.encodeToString(enc, 0);
        }
        catch(Exception ex)
        {
            Log.v(tag, "Err encrypt public key " +e.toString() );
        }
        return str;
    }
     public String decrypt_baomat(String input) // giai ma
    {
        try
        {
        	Log.v(tag, "bao mat dung key private de giai ma...");
            Cip = Cipher.getInstance("RSA");
            Cip.init(Cipher.DECRYPT_MODE,KeyPri);
            byte [] dec = Base64.decode(input, 0);
            byte []utf8 = Cip.doFinal(dec);
            return new String(utf8,"UTF8");
        }
        catch(Exception ex)
        {
        	 Log.v(tag, "Err decrypt pub_pri " +e.toString() );
            return null;
        }
    }

     public String encrypt_chungthuc(String input) // ma hoa su dung private key rsa
    {
        String str = "";
        try
        {
        	Log.v(tag, "chung thuc dung key pri de ma hoa...");
            Cip = Cipher.getInstance("RSA");
            Cip.init(Cipher.ENCRYPT_MODE, KeyPri);
            byte []utf8 = input.getBytes("UTF8");
            byte []enc = Cip.doFinal(utf8);
            str = Base64.encodeToString(enc, 0);
        }
        catch(Exception ex)
        {
        	 Log.v(tag, "Err encrypt pri pub " +e.toString() );
        }
        return str;
    }
     
    public String decrypt_chungthuc(String input) // giai ma su dung public key , dung chuc thuc
    {
        try
        {
        	Log.v(tag, "chung thuc dung key public de giai ma...");
            Cip = Cipher.getInstance("RSA");
            Cip.init(Cipher.DECRYPT_MODE,KeyPu);
            byte [] dec = Base64.decode(input, 0);
            byte []utf8 = Cip.doFinal(dec);
            return new String(utf8,"UTF8");
        }
        catch(Exception ex)
        {
        	 Log.v(tag, "Err decrypt pri  pub " +e.toString() );
            return null;
        }
    }
    
    public String sign(String input) // su dung key pri de ky vao van ban
    {
    	String output = "";
    	try 
    	{
    		//bam input bang sha1
			MessageDigest digest = MessageDigest.getInstance("SHA1");
			byte[] byte_digest = digest.digest(input.getBytes());
			
			//dung private key de ma hoa chuoi bam
			String str_digest = new String(byte_digest);
			output = encrypt_chungthuc(str_digest);
			Log.v(tag, "Sign thanh cong ...");
			
		} catch (Exception e) {
			// TODO: handle exception
			Log.v(tag, "Err sign  "+e.toString());
		}
    	return output;
    }
    
    public String de_sign(String input) // giai ma chuoi ma hoa ra cguoi hash
    {
    	String output = "";
    	try 
    	{
			output = decrypt_chungthuc(input);
		} catch (Exception e) {
			// TODO: handle exception
			Log.v(tag, "Err de sign  "+e.toString());
		}
    	return output;
    }
    
    public boolean check_sign(String m, String m1) //m la chuoi de so sanh, m1 la chuoi da duoc bam bang sha1 va ma hoa bang private cua ng gui
    {
    	try 
    	{
    		// su dung public key ng gui de ma hoa lay chuoi bam
    		String hash = decrypt_chungthuc(m1);
    		// bam chuoi m de lay chuoi hash
    		MessageDigest digest = MessageDigest.getInstance("SHA1");
    		byte[]byte_digest = digest.digest(m.getBytes());
    		String hash_m = new String(byte_digest);
    		
    		// so sanh
    		if(hash.equals(hash_m))
    		{
    			Log.v(tag, "xac nhan chung thuc..");
    			return true;
    		}
    		else
    		{
    			Log.v(tag, "Xac thuc khong hop le ..");
    			return false;
    		}
			
		} catch (Exception e) {
			// TODO: handle exception
			Log.v(tag, "Err check sign  "+e.toString());
			return false;
		}
    }
    
    public String hash_sha(String input) // bam chuoi m thanh chuoi hash
    {
    	String output = "";
    	try 
    	{
    		MessageDigest digest = MessageDigest.getInstance("SHA1");
    		byte[]byte_digest = digest.digest(input.getBytes());
    		output = new String(byte_digest);
		} catch (Exception e) {
			// TODO: handle exception 
			Log.e(tag, "err hash" +e.toString());
		}
    	return output;
    }
    
    

}
